/**
 * 构建重试管理器
 */
const logManager = require('./logManager');

class RetryManager {
  constructor() {
    this.retryAttempts = new Map(); // 记录每个项目的重试次数
  }

  /**
   * 执行带重试的构建任务
   */
  async executeWithRetry(projectId, buildFunction, options = {}) {
    const {
      maxAttempts = 3,           // 最大重试次数
      retryDelay = 5000,         // 重试间隔(ms)
      retryableErrors = [        // 可重试的错误类型
        'TIMEOUT',
        'NETWORK',
        'DEPENDENCY_INSTALL',
        'BUILD_COMMAND',
        'DOCKER_BUILD'
      ]
    } = options;

    let lastError;
    
    // 重置重试计数
    this.retryAttempts.set(projectId, 0);

    for (let attempt = 1; attempt <= maxAttempts; attempt++) {
      try {
        this.retryAttempts.set(projectId, attempt);
        
        if (attempt > 1) {
          logManager.sendRetryLog(projectId, attempt, maxAttempts, lastError);
          // 等待重试间隔
          await this.delay(retryDelay);
        }

        // 执行构建函数
        const result = await buildFunction(attempt);
        
        // 成功后清理重试记录
        this.retryAttempts.delete(projectId);
        
        if (attempt > 1) {
          logManager.sendLog(projectId, {
            level: 'success',
            message: `✅ 重试成功！经过${attempt}次尝试后构建完成`,
            data: { totalAttempts: attempt }
          });
        }
        
        return result;

      } catch (error) {
        lastError = error;
        
        // 检查是否为可重试的错误
        const isRetryable = this.isRetryableError(error, retryableErrors);
        
        if (attempt === maxAttempts || !isRetryable) {
          // 达到最大重试次数或不可重试错误
          this.retryAttempts.delete(projectId);
          
          logManager.sendLog(projectId, {
            level: 'error',
            message: `❌ 构建最终失败: 经过${attempt}次尝试后仍然失败`,
            data: { 
              totalAttempts: attempt,
              finalError: error.message,
              retryable: isRetryable
            }
          });
          
          throw error;
        }
        
        // 记录重试日志
        logManager.sendLog(projectId, {
          level: 'warning',
          message: `⚠️ 第${attempt}次构建失败: ${error.message}`,
          data: { 
            attempt, 
            maxAttempts, 
            willRetry: attempt < maxAttempts,
            error: error.message 
          }
        });
      }
    }
  }

  /**
   * 检查错误是否可重试
   */
  isRetryableError(error, retryableErrors) {
    const errorMessage = error.message?.toLowerCase() || '';
    const errorCode = error.code?.toUpperCase() || '';
    
    // 检查常见的可重试错误模式
    const retryablePatterns = [
      /timeout/i,
      /network/i,
      /connection/i,
      /enotfound/i,
      /econnreset/i,
      /npm.*install.*failed/i,
      /docker.*build.*failed/i,
      /node-sass.*binary/i,
      /gyp.*err/i,
      /python.*not.*found/i,
      /syntaxerror.*missing parentheses.*print/i,  // Python 2/3 兼容性问题
      /node-sass.*postinstall.*failed/i,           // node-sass安装失败
      /gyp.*configure.*error/i,                    // gyp配置错误
      /build failed with error code/i              // 通用构建失败
    ];

    // 检查错误码
    const retryableCodes = ['ETIMEDOUT', 'ENOTFOUND', 'ECONNRESET', 'ECONNREFUSED'];
    
    return retryablePatterns.some(pattern => pattern.test(errorMessage)) ||
           retryableCodes.includes(errorCode) ||
           retryableErrors.some(type => errorMessage.includes(type.toLowerCase()));
  }

  /**
   * 获取项目当前重试次数
   */
  getCurrentAttempt(projectId) {
    return this.retryAttempts.get(projectId) || 0;
  }

  /**
   * 延迟函数
   */
  delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  /**
   * 检查项目是否正在重试中
   */
  isRetrying(projectId) {
    return this.retryAttempts.has(projectId) && this.retryAttempts.get(projectId) > 1;
  }

  /**
   * 取消项目的重试
   */
  cancelRetry(projectId) {
    this.retryAttempts.delete(projectId);
    logManager.sendLog(projectId, {
      level: 'info',
      message: '🛑 构建重试已被用户取消',
      data: { cancelled: true }
    });
  }
}

// 创建单例实例
const retryManager = new RetryManager();

module.exports = retryManager;
